package com.chenjt.netty.one_helloWorld.helloWorld;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.net.URI;

/**
 * 注释：SimpleChannelInboundHandler : Inbound:对进来请求的处理  OutBound：响应的处理
 *
 * @author chenjt
 * @date 2024/8/8 9:42
 */
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {

    /**
     * 读取客户端的请求，并响应客户端
     * 注意：netty5.0的这个方法叫做messageReceived
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        /**
         * 查看HttpServerCodec将数据转换成什么类型的
         * 可以看到被转换成了两个类型：
         * 1.class io.netty.handler.codec.http.DefaultHttpRequest
         * 2.class io.netty.handler.codec.http.LastHttpContent$1
         * HttpObject是上述两个类型的父接口
         */
        System.out.println("msg类型" + msg.getClass());

        if(msg instanceof HttpRequest){

            HttpRequest httpRequest = (HttpRequest)msg;

            System.out.println("请求方法名：" + httpRequest.method().name());

            URI uri = new URI(httpRequest.uri());
            if("/favicon.ico".equals(uri.getPath())){
                // 浏览器访问时会有这个请求
                System.out.println("请求favicon.ico");
                return;
            }

            ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8);
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK, content);

            // 构建响应头
            // 这里用test/plain会导致浏览器访问时会以下载的方式响应
            // response.headers().set(HttpHeaderNames.CONTENT_TYPE,"test/plain");
            response.headers().set(HttpHeaderNames.CONTENT_TYPE,"application/json");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());

            // 调用writer只会把内容放到缓冲区里面，不会立即返回给客户端
            ctx.writeAndFlush(response);
        }

    }

}
